﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Ports;
using System.Linq;
using System.Runtime.Remoting.Channels;
using System.Text;
using System.Threading;
using CSharp_OPTControllerAPI;

namespace OptControllerLib
{
    public class OptController
    {
        /// <summary>
        /// 设备序列号
        /// </summary>
        private string m_strSN;
        public string StrSN
        {
            get => this.m_strSN;
        }

        Action<string> OPTLogout;
        /// <summary>
        /// 设备IP
        /// </summary>
        private string m_strIP;
        public string StrIP
        {
            get => this.m_strIP;
        }

        /// <summary>
        /// 控制器API
        /// </summary>
        private OPTControllerAPI OptCtlApi = null;

        ///// <summary>
        ///// 软件触发数组
        ///// </summary>
        //private OPTControllerAPI.SoftwareTriggerItem[] array;
        //private int[] channelArray;

        /// <summary>
        /// 设备连接状态
        /// </summary>
        public bool IsConnect
        {
            get
            {
                return (OptCtlApi == null) ? false : (OptCtlApi.IsConnect() == 0);
            }
        }


        /// <summary>
        /// 默认构造函数
        /// </summary>

        public OptController(string ip = "192.168.1.16", Action<string> logout = null)
        {

            m_strIP = ip;
            OptCtlApi = new OPTControllerAPI();
            LightChnLock = new Mutex[8];
            for (int i = 0; i < LightChnLock.Length; i++)
            {
                LightChnLock[i] = new Mutex();
            }
            if (logout != null)
            {
                this.OPTLogout += logout;
            }
        }

        /// <summary>
        /// 打开设备
        /// </summary>
        /// <param name="config"></param>
        /// <returns></returns>
        public int Open(object config)
        {
            int nRet = 0;

            nRet = OptCtlApi.CreateEthernetConnectionByIP(m_strIP);

            if (nRet != OPTControllerAPI.OPT_SUCCEED)
            {
                return -1;
            }

            //nRet = OptCtlApi.EnablePowerOffBackup(Config.EnablePowerOffBackup?1:0);
            //if (nRet != OPTControllerAPI.OPT_SUCCEED)
            //{
            //    Logout($"{Name} 设置掉电保存失败");
            //    return -1;
            //}
            return 0;
        }

        /// <summary>
        /// 关闭设备
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public int Close(object data)
        {
            try
            {
                int nRet = OptCtlApi.DestroyEthernetConnect();
                if (nRet != OPTControllerAPI.OPT_SUCCEED)
                {
                    return -1;
                }
                //m_isConnected = false;
                return 0;
            }
            catch (Exception ex)
            {
                Logout(ex.Message);
                return -1;
            }

        }

        /// <summary>
        /// 对通道设置亮度
        /// </summary>
        /// <param name="chn"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public int SetLightValue(int chn, uint data)
        {
            Stopwatch SdkTime = new Stopwatch();
            int ret = 0;
            if (LightChnLock[chn].WaitOne())
            {
                SdkTime.Restart();
                ret = OptCtlApi.SetIntensity(chn, (int)data);
                Logout( $"OPT设置亮度SDK耗时{SdkTime.ElapsedMilliseconds}");
                LightChnLock[chn].ReleaseMutex();
                return ret;
            }
            return -1;
        }

        Mutex LightOpenLock = new Mutex();
        Mutex[] LightChnLock;
        /// <summary>
        /// 设置亮度并触发IO
        /// </summary>
        /// <param name="chn"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public int SoftwareTrigger(int chn, uint data)
        { 
            Stopwatch runtime = new Stopwatch();
            runtime.Restart();
            if (data == 0)
            {
                OpenLight(chn);
                //OptCtlApi.TurnOnChannel(chn);
                Logout($"OPT点亮光源耗时{runtime.ElapsedMilliseconds}");
                return 0;
            }

            if (SetLightValue(chn, data) == 0)
            {
                Logout( $"OPT设置亮度总耗时{runtime.ElapsedMilliseconds}");

                runtime.Restart();

                    OpenLight(chn);
                    //OptCtlApi.TurnOnChannel(chn);
                
                Logout( $"OPT点亮光源耗时{runtime.ElapsedMilliseconds}");
                return 0;
            }
            return -1;
        }


        public void OpenLight(int chn)
        {
            Stopwatch SdkTime = new Stopwatch();
            if (LightChnLock[chn].WaitOne())
            {
                SdkTime.Restart();
                OptCtlApi.TurnOnChannel(chn); 
                Logout($"OPT设置打开通道SDK耗时{SdkTime.ElapsedMilliseconds}");
                LightChnLock[chn].ReleaseMutex();
            }
        }

        private void OPTCloseLight(int chn)
        {
            Stopwatch SdkTime = new Stopwatch();
            if (LightChnLock[chn].WaitOne())
            {
                SdkTime.Restart();
                OptCtlApi.TurnOffChannel(chn);
                Logout($"OPT设置关闭通道SDK耗时{SdkTime.ElapsedMilliseconds}");
                LightChnLock[chn].ReleaseMutex();
            }
        }



        /// <summary>
        /// 关闭光源
        /// </summary>
        /// <param name="chn"></param>
        /// <returns></returns>
        public int CloseLight(int chn)
        {
            OPTCloseLight(chn);
            //OptCtlApi.TurnOffChannel(chn);
            //SoftwareTrigger(chn, 0);
            return 0;
        }

        public void Logout(string log) 
        {
            OPTLogout?.Invoke(log);
        }

        /// <summary>
        /// 扫描控制器
        /// </summary>
        /// <param name="listStrSN"></param>
        public static void ControllerListInit(out string[] listStrSN)
        {
            try
            {
                StringBuilder snList = new StringBuilder();
                int nRet = new OPTControllerAPI().GetControllerListOnEthernet(snList);
                if (nRet != OPTControllerAPI.OPT_SUCCEED)
                {
                    listStrSN = null;
                    return;
                }

                listStrSN = snList.ToString().Split(',');
            }
            catch (Exception ex)
            {
                listStrSN = null;
            }
           
        }
    }
}
